#ifndef AVALON_SIGNALHANDLING_HPP
#define AVALON_SIGNALHANDLING_HPP
#include <boost/preprocessor/iteration/local.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include "Avalon/Base/Base.hpp"

namespace Avalon {
namespace SignalHandling {
  class ConnectionGroup;
  class GroupConnection;
  class QueuedSignalHandler;
  typedef boost::shared_ptr<QueuedSignalHandler> QueuedSignalHandlerPtr;
  class ScopedGroupConnection;
  class SignalSink;
  typedef boost::shared_ptr<SignalSink> SignalSinkPtr;
  class TaskSignalHandler;

  /*! \struct NullSlot
   *  \brief Defines a slot that does nothing.
   */
  template<typename Signal, int Arity = Signal::arity>
  struct NullSlot {};

  template<typename Signal>
  struct NullSlot<Signal, 0> {
    static void Slot() {}
  };

  #define AVALON_NULL_SLOT_PARAMETER_COUNT 10

  #define AVALON_NULL_SLOT_TYPE(z, n, a)                                       \
    BOOST_PP_COMMA_IF(n) typename Signal::template arg<n>::type

  #define BOOST_PP_LOCAL_MACRO(n)                                              \
  template<typename Signal>                                                    \
  struct NullSlot<Signal, n> {                                                 \
    static void Slot(BOOST_PP_REPEAT(n, AVALON_NULL_SLOT_TYPE, a)) {}          \
  };

  #define BOOST_PP_LOCAL_LIMITS (1, AVALON_NULL_SLOT_PARAMETER_COUNT)
  #include BOOST_PP_LOCAL_ITERATE()
  #undef AVALON_NULL_SLOT_PARAMETER_COUNT
  #undef AVALON_NULL_SLOT_TYPE
}
}

#endif // AVALON_SIGNALHANDLING_HPP
